(* graplc.ml *)
(* @authors Steven Edwards, Ryan Turner, Di Wen *)
(* Runs the parser, scanner, and compiler on an input program.*)
(* Command line flags: *)
(* -a : grapl pretty printer output (for debugging purposes)*)
(* -c : compile to class GraplProgram (default setting). User should redirect this output to GraplProgram.java *)
(* -n myClass : compile to class MyClass. User should redirect this output to MyClass.java. *)
(* -l : compile the standard library, GraplStdLib. User should redirect this output to GraplStdLib.java. NOTE: the library *)
(* will not function correctly unless compiled with this setting. *)

type action = Ast | Compile | NamedCompile | LibraryCompile (* | AstOnFile | JavaOnFile *)

let default_program_name = "GraplProgram"
let standard_library_name = "GraplStdLib"
let default_imports = ["lib*"; standard_library_name]
let std_lib_imports = ["lib*"]
let std_lib_init_string = "void initialize(Graph g, GraplLib l) \n{\n graph = g; \n library = l; \n}\n"

let _ =
  if Array.length Sys.argv > 1 then let flags = Sys.argv.(1) in
    let mode = 
			if String.contains flags 'q' then Compile.Quiet else 
			if String.contains flags 'v' then Compile.Verbose else Compile.Verbose				
		and action = 						
			if String.contains flags 'a' then Ast else
			if String.contains flags 'c' then Compile else
		  if String.contains flags 'n' then NamedCompile else
			if String.contains flags 'l' then LibraryCompile else Compile 
		in
  let lexbuf = Lexing.from_channel stdin in
  let (vars, funcs)  = Parser.program Scanner.token lexbuf in
  match action with

	(* Grapl pretty printer -- for debugging purposes *)
  | Ast -> let listing = Gpp.string_of_program (vars, funcs)
           in print_string listing
	
	(* Normal compile with default output name. User must redirect output to GraplProgram.java. *)
  | Compile -> let listing = Jpp.string_of_program (default_imports, (Compile.compile vars funcs default_program_name mode))
               in print_string listing
							
	(* Compile with named output. User must redirect output to a Java file with same name as the argument. *)				
  | NamedCompile -> let listing = Jpp.string_of_program (default_imports, (Compile.compile vars funcs (Sys.argv.(2))) mode)
               in print_string listing
							
	(* Library compile. Incoporates a dirty little hack that passes global params to the standard library class. *)
  | LibraryCompile -> let listing = Jpp.string_of_program (std_lib_imports, (Compile.compile vars funcs standard_library_name mode))
               in print_string (listing ^ std_lib_init_string)
																					
(* | AstOnFile -> let oc = if Sys.argv.(2) == ">" then open_out Sys.argv.(3) else open_out Sys.argv.(5) 
                 in fprintf oc "%s\n" Gpp.string_of_program program; 
                 close_out oc;
  | JavaOnFile -> let oc = if Sys.argv.(2) == ">" then open_out Sys.argv.(3) else open_out Sys.argv.(5) 
                 in fprintf oc "%s\n" Jpp.string_of_program program; 
                 close_out oc;  
*)